package com.godofgamblers.hotelmanagementsystem.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import com.godofgamblers.hotelmanagementsystem.realm.UserRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

import java.util.LinkedHashMap;
import java.util.Map;

/*

@author huanglang

@create_time 2019-10-09 19:33

Nothing is difficult but bugs

*/

@Configuration
public class ShiroConfig {
    //userRealm
    @Bean
    public UserRealm userRealm(EhCacheManager ehCacheManager,HashedCredentialsMatcher matcher) {
        UserRealm userRealm = new UserRealm();
        //开启缓存
        userRealm.setCachingEnabled(true);
        //指定认证的缓存 开启缓存认证时查询的数据
        userRealm.setAuthenticationCachingEnabled(true);
        //缓存存放地址
        userRealm.setAuthenticationCacheName("authenticationCacheAddress");
        //指定授权的缓存 开启缓存授权时查询的数据
        userRealm.setAuthorizationCachingEnabled(true);
        //缓存存放地址
        userRealm.setAuthorizationCacheName("authorizationCacheAddress");
//        //加密
//        userRealm.setCredentialsMatcher(matcher);
        return userRealm;
    }

    //session管理器
    @Bean
    public DefaultWebSessionManager sessionManager() {
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        //session超时时间
        sessionManager.setGlobalSessionTimeout(1800000);
        //是否删除无效、过期的session
        sessionManager.setDeleteInvalidSessions(true);
        return sessionManager;
    }

    //缓存管理器
    @Bean
    public EhCacheManager ehCacheManager() {
        EhCacheManager ehCacheManager = new EhCacheManager();
        ehCacheManager.setCacheManagerConfigFile("classpath:ehcache.xml");
        return ehCacheManager;
    }

    //配置shiro的注解 shiro的注解一定要放在第一个被加载的spring配置文件中，才能使用
    //1 shiro的注解通过AOP实现的，需要设置代理
    @Bean
    @DependsOn("lifecycleBeanPostProcessor")
    @ConditionalOnMissingBean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
        //是否代理（被代理类）目标类
        defaultAAP.setProxyTargetClass(true);
        return defaultAAP;
    }
    //2 配置通知用于开启注解
    @Bean
    public AuthorizationAttributeSourceAdvisor sourceAdvisor(DefaultWebSecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor sourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        //设置指定安全管理器
        sourceAdvisor.setSecurityManager(securityManager);
        return sourceAdvisor;
    }

    //3 配置shiro的生命周期管理器
    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    //安全管理器
    @Bean
    public DefaultWebSecurityManager securityManager(UserRealm userRealm,DefaultWebSessionManager sessionManager,EhCacheManager ehCacheManager) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //配置Realm
        securityManager.setRealm(userRealm);
        //配置session管理器
        securityManager.setSessionManager(sessionManager);
        //配置ehcache缓存管理器
        securityManager.setCacheManager(ehCacheManager);
        return securityManager;
    }

    //shiro过滤器
    @Bean
    public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager manager) {
        ShiroFilterFactoryBean filter = new ShiroFilterFactoryBean();
        //设置安全管理器
        filter.setSecurityManager(manager);
        //登录界面
        filter.setLoginUrl("/indexs");

        //配置错误页面,没有权限跳转到指定页面
        filter.setUnauthorizedUrl("/login");

        //设置过滤器链
        Map<String, String> filterMap = new LinkedHashMap<>();

//        //服务器请求
        filterMap.put("/register", "anon");
        filterMap.put("/login", "anon");
        filterMap.put("/indexs", "anon");
        filterMap.put("/loginCheck","anon");
        filterMap.put("/getCode_phone","anon");
        filterMap.put("/getCode","anon");
        filterMap.put("/registerPage","anon");
        filterMap.put("/registerCheck","anon");

        filterMap.put("/commentPage","anon");
        filterMap.put("/about","anon");
        filterMap.put("/contact","anon");
        filterMap.put("/dinning","anon");
        filterMap.put("/gallery","anon");
        filterMap.put("/news","anon");
        filterMap.put("/rooms","anon");
        filterMap.put("/showRoom","anon");
        filterMap.put("/findLogin","anon");

        filterMap.put("/pay/**","anon");
        filterMap.put("/addMoney/**","anon");

        filterMap.put("/dinning","anon");


       filterMap.put("/logout", "logout");
        //静态资源
        filterMap.put("/assets/**", "anon");
        filterMap.put("/bootstrapt/**", "anon");
        filterMap.put("/css/**", "anon");
        filterMap.put("/data/**", "anon");
        filterMap.put("/font-awesome/**", "anon");
        filterMap.put("/fonts/**", "anon");
        filterMap.put("/icons-reference/**", "anon");
        filterMap.put("/images/**", "anon");
        filterMap.put("/jquery/**", "anon");
        filterMap.put("/js/**", "anon");
        filterMap.put("/js1/**", "anon");
        filterMap.put("/libraries/**", "anon");
        filterMap.put("/vendor/**", "anon");
        filterMap.put("/registerPage","anon");
        filterMap.put("/registerCheck","anon");

        filterMap.put("/logout", "logout");
//        filterMap.put("/**", "anon");
       filterMap.put("/**", "authc");
        filter.setFilterChainDefinitionMap(filterMap);
        return filter;
    }

    //加密类型、次数
    @Bean
        public  HashedCredentialsMatcher credentialsMatcher() {
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
        matcher.setHashAlgorithmName("MD5");
        matcher.setHashIterations(1024);
        return matcher;
    }

    /**
     * cookie对象;
     * rememberMeCookie()方法
     */

    //创建在html中使用shiro标签时需要的对象,如果不创建html中shiro标签无法正常使用
   @Bean
    public ShiroDialect dialect() {
        return new ShiroDialect();
    }
}
